home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / formats / urt / toolkit.mss < prev    next >
Text File  |  1994-10-02  |  29KB  |  633 lines

  1. @make(Article)
  2. @Device(PostScript)
  3. @Disable(FigureContents)
  4. @LibraryFile(Mathematics10)
  5.  
  6. @Modify(Description, LeftMargin +1.5inch, Indent -1.25inch, below 0.5 lines)
  7.  
  8. @Define(FigureFilename, Above 0, Below 0, Centered, Font BodyFont,FaceCode I )
  9.  
  10. @comment( These macros define how pictures are printed out.  Since the raster
  11.       images take a *long* time to print for the whole paper, this allows
  12.       them to be stubbed out.
  13.  
  14.       Use the first form for printing drafts, the second for
  15.       actually printing the images.  Of course, this assumes you have
  16.       a PostScript output device. )
  17.  
  18. @form(RLEpicture="@blankSpace[@Parm(Size)]@FigureFilename[@Parm(PostScript)]")
  19. @comment{
  20. @form(RLEpicture="@Picture[ Size @Parm(Size),
  21.                 PostScript=<@Parm(PostScript)> ]")
  22. }
  23.  
  24.  
  25. @Comment{This document uses "@F" for bold typewriter font.
  26.      I know it isn't documented, but it's exactly what I want.
  27.      If you're using something other than PostScript, the following
  28.      re-defines it to be the typewriter font:
  29.  
  30.        @Textform(F="@T[@parm(Text)]")
  31.     }
  32.  
  33. @comment[This font is much better than Times, but we can't
  34.          assume all PostScript printers have it.
  35.          @style(FontFamily=NewCenturySchoolbook)
  36.         ]
  37. @Style(FontFamily=TimesRoman)
  38.  
  39. @style(Spacing=1)  @comment(1.1?)
  40. @comment[ no nuke page headings @PageHeading(Left "") ]
  41.  
  42. @MajorHeading(The Utah Raster Toolkit)
  43.  
  44. @begin(Center)
  45. John W. Peterson
  46. Rod G. Bogart
  47. @i(and)
  48. Spencer W. Thomas
  49. @blankSpace(1 line)
  50. University of Utah, Department of Computer Science@footnote(Originally presented at the third Usenix Workshop on Graphics, Monterey California, November 1986)
  51. Salt Lake City, Utah
  52. @end(Center)
  53. @blankspace(1 inch)
  54. @Heading(Abstract)
  55. @begin(quotation)
  56. The Utah Raster Toolkit is a set of programs for manipulating and
  57. composing raster images.  These tools are based on the Unix concepts of
  58. pipes and filters, and operate on images in much the same way as the
  59. standard Unix tools operate on textual data.
  60. The Toolkit uses a special run length encoding (RLE) format for
  61. storing images and interfacing between the various programs.  This
  62. reduces the disk space requirements for picture storage and provides a
  63. standard header containing descriptive information about an image.
  64. Some of the tools are able to work directly with the compressed
  65. picture data, increasing their efficiency.  A
  66. library of C routines is provided for reading and writing the RLE
  67. image format, making the toolkit easy to extend.
  68.  
  69. This paper describes the individual tools, and gives several examples of
  70. their use and how they work together.  Additional topics that arise in
  71. combining  images, such as how to combine color table information from
  72. multiple sources, are also discussed.
  73. @end(Quotation)
  74. @blankspace(3 lines)
  75.  
  76. @comment(This turns on two column mode - IT ALSO DIES WITH A BUS ERROR
  77.     @begin[Text, columns=2, boxed, LineWidth = 3.2 inch, 
  78.                columnMargin = 0.5 inch])
  79.  
  80. @section(Introduction)
  81.  
  82. Over the past several years, the University of Utah Computer Graphics Lab has
  83. developed several tools and techniques for generating, manipulating and
  84. storing images.  At first this was done in a somewhat haphazard manner -
  85. programs would generate and store images in various formats (often dependent
  86. on particular hardware) and data was often not easily interchanged between
  87. them.  More recently, some effort has been made to standardize the image
  88. format, develop an organized set of tools for operating on the images, and
  89. develop a subroutine library to make extending this set of tools easier.  This
  90. paper is about the result of this effort, which we call the @i(Utah Raster
  91. Toolkit.)  Using a single efficient image format, the toolkit provides a number
  92. of programs for performing common operations on images.  These are in turn
  93. based on a subroutine library for reading and writing the images.
  94.  
  95. @section(Origins)
  96. The idea for the toolkit arose while we were developing an image
  97. compositor.  The compositor (described in detail in section
  98. @ref(comp)) allows images to be combined in various ways.  We found
  99. that a number of simple and independent operations were frequently
  100. needed before images could be composited together.
  101.  
  102. With the common image format, the subroutine library for manipulating
  103. it, and the need for a number of independent tools, the idea of a
  104. "toolkit" of image manipulating programs arose.  These tools are
  105. combined using the Unix shell, operating on images
  106. much like the standard Unix programs operate on textual data.  For
  107. example, a Unix user would probably use the sequence of commands:
  108. @ProgramExample[
  109.     cat /etc/passwd | grep Smith | sort -t: +4.0 | lpr
  110. ]
  111. to print a sorted list of all users named "Smith" in the system
  112. password file.  Similarly, the Raster Toolkit user might do
  113. something like:
  114. @ProgramExample[
  115.     cat image.rle | avg4 | repos -p 0 200 | getfb
  116. ]
  117. to downfilter an image and place it on top of the frame buffer screen.  The
  118. idea is similar to a method developed by Duff @cite(zcomp) for three
  119. dimensional rendering.
  120.  
  121. @section(The RLE format)
  122. The basis of all of these tools is a Run Length Encoded image format@cite(RLE).
  123. This format is designed to provide an efficient, device
  124. independent means of storing multi-level raster images.  It is not
  125. designed for binary (bitmap) images.  It is built on several basic
  126. concepts.  The central concept is the @i[channel].  A channel
  127. corresponds to a single color, thus there are normally separate red, green and
  128. blue channels.  Up to 255 color channels are
  129. available for use; one channel is reserved for coverage ("alpha")
  130. data.  Although the format supports arbitrarily deep channels, the
  131. current implementation is restricted to 8 bits per channel.  An RLE
  132. file is treated as a byte stream, making it independent of host byte ordering.
  133.  
  134. Image data is stored in an RLE file in a scanline form, with the data for
  135. each channel of the scanline grouped together.  Runs of identical pixel
  136. values are compressed into a count and a value.  However, sequences of
  137. differing pixels are also stored efficiently (i.e, not as a sequence of single
  138. pixel runs).
  139.  
  140. @subsection(The RLE header)
  141. The file header contains a large amount of information about the image.
  142. This includes: 
  143. @begin(Itemize)
  144. The size and position on the screen,
  145.  
  146. The number of channels saved and the number of bits per channel
  147. (currently, only eight bits per channel is supported),
  148.  
  149. Several flags, indicating: how the background should be handled,
  150. whether or not an alpha channel was saved, if picture comments were saved,
  151.  
  152. The size and number of channels in the color map, (if the color map is
  153. supplied),
  154.  
  155. An optional background color,
  156.  
  157. An optional color map,
  158.  
  159. An optional set of comments.  The comment block contains any number of
  160. null-terminated text strings.  These strings are conventionally of the
  161. form "name=value", allowing for easy retrieval of specific information.
  162. @end(Itemize)
  163.  
  164. @SubSection(The scanline data)
  165. The scanline is the basic unit that programs read and write.
  166. It consists of a sequence of operations, such as @i[Run],
  167. @i[SetChannel], and @i[Pixels], describing the actual image.  An image is
  168. stored starting at the lower left corner and proceeding upwards in order of
  169. increasing scanline number.  Each operation and its associated data takes up
  170. an even number of bytes, so that all operations begin on a 16 bit boundary.
  171. This makes the implementation more efficient on many architectures.
  172.  
  173. Each operation is identified by an 8 bit opcode, and may have one or more
  174. operands.  Single operand operations fit into a single 16 bit word if the
  175. operand value is less than 256.  So that operand values are not limited to
  176. the range 0..255, each operation has a @i[long] variant, in which the byte
  177. following the opcode is ignored and the following word is taken as a 16 bit
  178. quantity.  The long variant of an opcode is indicated by setting the bit 0x40
  179. in the opcode (this allows for 64 opcodes, of which 6 have been used so far.)
  180.  
  181. The current set of opcodes include:
  182.  
  183. @begin(Description)
  184. SkipLines@\Increment the @i[scanline number] by the operand value, terminating
  185. the current scanline.
  186.  
  187. SetColor@\Set the @i[current channel] to the operand value.
  188.  
  189. SkipPixels@\Skip over pixels in the current scanline.
  190. Pixels skipped will be left in the background color.
  191.  
  192. PixelData@\Following this opcode is a sequence of pixel values.  The length
  193. of the sequence is given by the operand value.
  194.  
  195. Run@\This is the only two operand opcode.  The first operand is the length
  196. (@i[N]) of the run.  The second operand is the pixel value, followed by a
  197. filler byte if necessary@Footnote(E.g., a 16 bit pixel value would not need a
  198. filler byte.).  The next @i[N] pixels in the scanline are set to
  199. the given pixel value.
  200.  
  201. EOF@\This opcode has no operand, and indicates the end of the RLE file.  It
  202. is provided so RLE files may be concatenated together and still be
  203. correctly interpreted.  It is not required, a physical end of file also
  204. indicates the end of the RLE data.
  205. @End(Description)
  206.  
  207. @SubSection(Subroutine Interface)
  208.  
  209. Two similar subroutine interfaces are provided for reading and writing files
  210. in the RLE format.  Both read or write a scanline worth of data at a time.  A
  211. simple "row" interface communicates in terms of arrays of pixel values.  It
  212. is simple to use, but slower than the "raw" interface, which uses arrays of
  213. "opcode" values as its communication medium.
  214.  
  215. In both cases, the interface must be initialized by calling a setup function.
  216. The two types of calls may be interleaved; for example, in a rendering
  217. program, the background could be written using the "raw" interface, while
  218. scanlines containing image data could be converted with the "row" interface.
  219. The package allows multiple RLE streams to be open simultaneously, as is
  220. necessary for use in a compositing tool, for example.  All data relevant to a
  221. particular RLE stream is contained in a "globals" structure.  This
  222. structure essentially echoes the information in the RLE header, along
  223. with current state information about the RLE stream.
  224.  
  225. @section(The tools)
  226. @subsection(The image compositor - Comp)
  227. @label(comp)
  228. @F(Comp) implements an image compositor based on the compositing algorithms
  229. presented in @cite(Alpha).  The compositing operations are based on the
  230. presence of an alpha channel in the image.  This extra channel usually defines
  231. a mask which represents a sort of a cookie-cutter for the image.  This is the 
  232. case when alpha is 255 (full coverage) for pixels inside the shape, zero
  233. outside, and between zero and 255 on the boundary.  
  234. When the compositor operates on images of the cookie-cutter style, the
  235. operations behave as follows:
  236. @begin(Description)
  237. A @b(over) B (the default)@\The result will be the union of the two
  238. image shapes, with A obscuring B in the region of overlap.
  239.  
  240. A @b(atop) B@\The result shape is the same as image B, with A obscuring
  241. B where the image shapes overlap. (Note that this differs from
  242. "over" because the portion of A outside the shape of B will not
  243. be in the result image.)
  244.  
  245. A @b(in) B@\The result is simply the image A cut by the shape of B.
  246. None of the image data of B will be in the result.
  247.  
  248. A @b(out) B@\The result image is image A with the shape of B cut out.
  249.  
  250. A @b(xor) B@\The result is the image data from both images that is
  251. outside the overlap region.  The overlap region will be blank.
  252.  
  253. A @b(plus) B@\The result is just the sum of the image data.  This
  254. operation is actually independent of the alpha channels.
  255.  
  256. @end(Description)
  257.  
  258.  
  259. The alpha channel can also represent a semi-transparent mask for the
  260. image.  It would be similar to the cookie-cutter mask, except the
  261. interior of the shape would have alpha values that represent partial
  262. coverage; e.g. 128 is half coverage.  When one of the images to be
  263. composited is a semi-transparent mask, the following operations have
  264. useful results:
  265. @begin(Description)
  266. Semi-transparent A @b(over) B@\The image data of B will be blended with
  267. that of A in the semi-transparent overlap region.  The resulting
  268. alpha channel is as transparent as that of image B.
  269.  
  270. A @b(in) Semi-transparent B@\The image data of A is scaled by the
  271. mask of B in the overlap region.  The alpha channel is
  272. the same as the semi-transparent mask of B.
  273. @end(Description)
  274.  
  275. If the picture to be composited doesn't have an alpha channel present, comp
  276. assumes an alpha of 255 (i.e., full coverage) for non-background pixels and
  277. an alpha of zero for background pixels.
  278.  
  279. Comp is able to take advantage of the size information for the two
  280. images being composited.  For example, if a small picture is being
  281. composited over a large backdrop, the actual compositing arithmetic
  282. is only performed on a small portion of the image.  By looking at the
  283. image size in the RLE header, comp performs the compositing operation
  284. only where the images overlap.  For the rest of the image the
  285. backdrop is copied (or not copied, depending on the compositing
  286. operation).  The "raw" RLE read and write routines are used to perform
  287. this copy operation, thus avoiding the cost of compressing and
  288. expanding the backdrop as well.
  289.  
  290. @subsection(Basic image composition - Repos and Crop)
  291. @F(Repos) and @F(crop) are the basic tools for positioning and
  292. arranging images to be fed to the compositor.  Crop simply throws away
  293. all parts of the image falling outside the rectangle specified.  Repos
  294. positions an image to a specific location on the screen, or moves it
  295. by an incremental amount.  Repos does not have to modify any of the
  296. image data, it simply changes the position specification in the RLE
  297. header.  In order to simplify the code, the Raster Toolkit does not
  298. allow negative pixel coordinates in images.
  299.  
  300. @subsection(Changing image orientation and size - Flip, Fant and Avg4)
  301. Two tools exist for changing the orientation of an image on the screen.
  302. @F(Flip) rotates an image by 90 degrees right or left, turns an image
  303. upside down, or reverse it from right to left.  @F(Fant) rotates an image an
  304. arbitrary number of degrees from -45 to 45.  In order to get rotation beyond 
  305. -45 to 45, flip and fant can be combined, for example:
  306. @ProgramExample[
  307.     flip -r < upright.rle | fant -a 10 > rotated.rle
  308. ]
  309. rotates an image 100 degrees.  Fant is also able to scale images by an
  310. arbitrary amount in X and Y.  A common use for this is to stretch or shrink
  311. an image to correct for the aspect ratio of a particular frame buffer. Many
  312. frame buffers designed for use with standard video hardware display a
  313. picture of 512x480 pixels on a screen with the proportions 4:3, resulting in
  314. an overall pixel aspect ratio of 6:5.  If the picture @F[kloo.rle] is
  315. digitized or computed assuming a 1:1 aspect ratio (square pixels), the
  316. command: 
  317. @ProgramExample[
  318.     cat kloo.rle | fant -s 1.0 1.2 | getfb
  319. ]
  320. correctly displays the image on a frame buffer with a 6:5 aspect ratio.
  321. Fant is implemented using a two-pass subpixel sampling algorithm@cite(fant). 
  322. This algorithm performs the spatial transform (rotate and/or scale) first
  323. on row by row basis, then on a column by column basis.  Because the
  324. transformation is done on a subpixel level, fant does not introduce aliasing
  325. artifacts into the image.
  326.  
  327. @F(Avg4) downfilters an RLE image into a resulting image of 1/4th the
  328. size, by simply averaging four pixel values in the input image to
  329. produce a single pixel in the output.  If the original image does not
  330. contain an alpha channel, avg4 creates one by counting the number of
  331. non-zero pixels in each group of four input pixels and using the count
  332. to produce a coverage value.  While the alpha channel produced this
  333. way is crude (only four levels of coverage) it is enough to make a
  334. noticeable improvement in the edges of composited images.  One use for
  335. avg4 is to provide anti-aliasing for rendering programs that perform
  336. no anti-aliasing of their own.  For example, suppose @F[huge.rle] is a 4k
  337. x 4k pixel image rendered without anti aliasing and without an alpha
  338. channel.  Executing the commands:
  339. @ProgramExample[
  340.     cat huge.rle | avg4 | avg4 | avg4 > small.rle
  341. ]
  342. produces an image @F[small.rle] with 64 (8x8) samples per pixel and an
  343. alpha channel with smooth edges.  
  344.  
  345. Images generated from this approach are as good as those produced by direct
  346. anti-aliasing algorithms such as the A-buffer @cite(Abuffer).
  347. However, a properly implemented A-buffer renderer produces images nearly an
  348. order of magnitude faster.
  349.  
  350.  
  351. @subsection(Color map manipulation - Ldmap and Applymap)
  352.  
  353. As mentioned previously, RLE files may optionally contain a color map for the
  354. image.  @F(Ldmap) is used to create or modify a color map within an RLE file.
  355. Ldmap is able to create some standard color maps, such as linear maps with
  356. various ramps, or maps with various gamma corrections.  Color maps may also be
  357. read from a simple text file format, or taken from other RLE files.  Ldmap
  358. also performs @i(map composition), where one color map is used as in index
  359. into the other.  An example use for this is to apply a gamma correction to an
  360. image already having a non-linear map.  
  361.  
  362. @F(Applymap) applies the color map in an rle file
  363. to the pixel values in the file.  For example, if the color map
  364. in @F[kloo.rle] contained a color map with the entries (for the red channel):
  365. @begin(Figure)
  366. @verbatim[
  367.     Index   Red color map
  368.     0:    5
  369.     1:     7
  370.     2:    9
  371. ]
  372. @end(Figure)
  373.  
  374. Then a (red channel) pixel value of zero would be displayed with an
  375. intensity of five (assuming the display program used the color map in
  376. @F[kloo.rle]).  When kloo.rle is passed through applymap,
  377. @ProgramExample[
  378.     cat kloo.rle | applymap > kloo2.rle
  379. ]
  380. pixels that had a value of zero in @f[kloo.rle] now have a value of
  381. five in @f[kloo2.rle], pixel values of one would now be seven, etc.
  382. When displaying the images on a frame buffer, @f[kloo2.rle] appears
  383. the same with a linear map loaded as @F(kloo.rle) does with its special
  384. color map loaded.
  385.  
  386. One use for these tools is merging images with different compensation
  387. tables.  For example, suppose image @F[gam.rle] was computed so that
  388. it requires a gamma corrected color table (stored in the RLE file) to
  389. be loaded to look correct on a particular monitor, and image @F(lin.rle)
  390. was computed with the gamma correction already taken into
  391. consideration (so it looks correct with a linear color table loaded).
  392. If these two images are composited together without taking into
  393. consideration these differences, the results aren't correct (part of
  394. the resulting image is either too dim or washed out).  However,
  395. we can use applymap to "normalize" the two images to using a linear
  396. map with:
  397. @ProgramExample[
  398. cat gam.rle | applymap | comp - lin.rle | ldmap -l > result.rle
  399. ]
  400.  
  401. @subsection( Generating backgrounds )
  402. Unlike most of the toolkit programs which act as filters, @F(background) just
  403. produces output.  Background either produces a simple flat field, or it
  404. produces a field with pixel intensities ramped in the vertical
  405. direction.  Most often background is used simply to provide a colored
  406. backdrop for an image.
  407. Background is another example of a program that takes advantage of the "raw"
  408. RLE facilities.  Rather than generating the scanlines and compressing them,
  409. background simply generates the opcodes required to produce each scanline.
  410.  
  411. @subsection( Converting full RGB images to eight bits - to8 and tobw )
  412. Although most of the time we prefer to work with full 24 bit per pixel images,
  413. (32 bits with alpha) we often need the images represented with eight bits per
  414. pixel.  Many inexpensive frame buffers (such as the AED 512) and many personal
  415. color workstations (VaxStation GPX, Color Apollos and Suns) are
  416. equipped with eight bit displays.
  417.  
  418. @F(To8) converts a 24 bit image to an eight bit image by applying a dither
  419. matrix to the pixels.  This basically trades spatial resolution for color
  420. resolution.  The resulting image has eight bits of data per pixel, and also
  421. contains a special color map for displaying the dithered image (since most
  422. eight bit frame buffers still use 24 bit wide color table entries).
  423.  
  424. @F(Tobw) converts a picture from 24 bits of red, green, and blue to an
  425. eight bit gray level image.  It uses the standard television YIQ
  426. transformation of
  427. @begin(MathDisplay)
  428.     graylevel#=#@r[0.35]#*#red#+#@r[0.55]#*#green#+#@r[0.10]#*#blue.
  429. @end(MathDisplay)
  430. These images are often preferred when displaying the image on an eight bit
  431. frame buffer and shading information is more important than color.
  432.  
  433. @begin(Comment)
  434.  
  435. *** This section needs a for-real mathematical description.  Spencer
  436. *** couldn't come up with one off hand. ***
  437.  
  438. @subsection( Compressing dynamic range of image - unexp )
  439. Some image synthesis programs may generate images where the full
  440. dynamic range is not known ahead of time.
  441. @end(Comment)
  442.  
  443. @section( Interfacing to the RLE toolkit )
  444. In order to display RLE images, a number of programs are provided for
  445. displaying the pictures on various devices.  These display programs all read
  446. from standard input, so they are conveniently used as the end of a raster
  447. toolkit pipeline.  The original display program, @F(getfb), displays images
  448. on our ancient Grinnell GMR-27 frame buffer.  Many display programs have
  449. since been developed:
  450. @begin(Description)
  451. @F[getcx]@\displays images on a Chromatics CX1500
  452.  
  453. @F[getiris]@\displays an image on an Iris workstation (via ethernet)
  454.  
  455. @F[getX]@\for the X window system
  456.  
  457. @F[getap]@\for the Apollo display manager
  458.  
  459. @F[gethp]@\for the Hewlett-Packard Series 300 workstation color display
  460.  
  461. @F[rletops]@\converts an RLE file to gray-level PostScript
  462. output@footnote(@f[Rletops] was used to produce the figures in this paper.)
  463. @end(Description)
  464.  
  465. The @F[getX], @F[getap] and @F[gethp] programs automatically perform the
  466. dithering required to convert a 24 bit RLE image to eight bits (for
  467. color nodes) or one bit (for bitmapped workstations).  Since all of
  468. these workstations have high resolution (1Kx1K) displays, the trade of
  469. spatial resolution for color resolution produces very acceptable
  470. results.  Even on bitmapped displays the image quality is good enough
  471. to get a reasonable idea of an image's appearance.
  472.  
  473. Two programs, @F(painttorle) and @F(rletopaint) are supplied to convert
  474. MacPaint images to RLE files.  This offers a simple way to add text or
  475. graphic annotation to an RLE image (although the resolution is somewhat low).
  476.  
  477. @Section( Examples )
  478. A typical use for the toolkit is to take an image generated
  479. with a rendering program, add a background to it, and display the
  480. result on a frame buffer:
  481. @programExample[
  482. rlebg 250 250 250 -v | comp image.rle - | getfb
  483. ]
  484.  
  485. What follows are some more elaborate applications:
  486.  
  487. @subSection( Making fake shadows )
  488. In this exercise we take the dart (Figure @ref(original_dart)a) and stick it
  489. into the infamous mandrill, making a nice (but completely fake) shadow
  490. along the way.
  491. @Figure{
  492. @RLEPicture(Size=3 inch, PostScript=[pics/dart_and_strtch.ps])
  493. @caption[@b(a:) Original dart image. @b(b:) Rotated and stretched dart.]
  494. @tag(Original_dart)
  495. }
  496.  
  497. First the image of the dart is rotated by 90 degrees (using @F[rleflip
  498. -l] and then stretched in the X direction (using @F[fant -s 1.3 1.0])
  499. to another image we can use as a shadow template, figure
  500. @ref(Original_dart)b.  Then we take this image, @F[dart_stretch_rot.rle], 
  501. and do:
  502. @programExample[
  503. rlebg 0 0 0 175 \
  504.    | comp -o in - dart_stretch_rot.rle > dart_shadow.rle
  505. ]
  506.  
  507. This operation uses the stretched dart as a cookie-cutter, and the
  508. shape is cut out of a black image, with a coverage mask (alpha
  509. channel) of 175.  Thus when we composite the shadow (figure
  510. @ref(DartShadow)a) over the mandrill image, it lets 32% of the mandrill
  511. through ((255 - 175) / 255 = 32%) with the rest being black.
  512. @Figure{
  513. @RLEPicture(Size=3 inch, PostScript=[pics/dart_shadow_and_monkey.ps])
  514. @caption[@b(a:) Dart shadow mask. @b(b:) Resulting skewered baboon.]
  515. @tag(DartShadow)
  516. @tag(stuck_monkey)
  517. }
  518.  
  519. Now all we have left to do is to composite the dart and the shadow
  520. over the mandrill image, and the result is figure @ref(stuck_monkey)b.
  521. Note that since the original dart image was properly anti-aliased, no aliasing
  522. artifacts were introduced in the final image.
  523.  
  524. @subsection( Cutting holes )
  525.  
  526. In this example we start out out with a single bullet hole, created
  527. with the same modelling package that produced the
  528. dart.@footnote(The bullet hole was modeled with cubic B-splines.  
  529. Normal people probably would have painted something like this...)  
  530. First the hole (which originally filled the screen) is 
  531. downfiltered to a small size, with
  532. @programExample[
  533. avg4 < big_hole.rle | avg4 | avg4 > smallhole.rle
  534. ]
  535. @Figure{
  536. @RLEPicture(Size=3 inch, PostScript=[pics/bullet_holes_and_shot_turb.ps])
  537. @caption[@b(a:) A set of bullet holes. @b(b:) A shot-up turbine blade.]
  538. @tag(blade_with_holes)
  539. @tag(multiple_holes)
  540. }
  541.  
  542. Now by invoking @f[repos] and @f[comp] several times in a row, 
  543. a set of shots is built up (Figure @ref(multiple_holes)a)
  544.  
  545. To shoot up the turbine blade, the @i[atop] operator of comp is used.  This
  546. works much like @i[over], except the bullet holes outside of the turbine
  547. blade don't appear in the resulting image (Figure
  548. @ref(blade_with_holes)b)  Note how the top left corner is just grazed.
  549.  
  550. But there's still one catch.  Suppose we want to display the shot-up
  551. turbine blade over a background of some sort.  We want to be see the background
  552. through the holes.  To do this we come up with another mask to cut
  553. away the centers of the bullet holes already on the turbine blade so
  554. we can see through them (Figure @ref(hole_center_masks)a).
  555. @Figure{
  556. @RLEPicture(Size=3 inch, PostScript=[pics/center_masks_and_fin_turb.ps])
  557. @caption[@b(a:) Cut-away masks for the bullet hole centers. 
  558. @b(b:) Finished turbine blade]
  559. @tag(blade_with_background)
  560. @tag(hole_center_masks)
  561. }
  562. Now we can see through the blade (Figure @ref(blade_with_background)b).
  563.  
  564. @subsection( Integrating digitized data )
  565. In this example, we take a raw digitized negative and turn it into a useful
  566. frame buffer image.  Figure @ref(raw_pahriah)a shows the original image from 
  567. the scanner.  First the image is cropped to remove the excess digitized 
  568. portion, then rotated into place with @f(flip -r), resulting in Figure 
  569. @ref(raw_pahriah)b.
  570.  
  571. @Figure{
  572. @RLEPicture(Size=3 inch, PostScript=[pics/scanned_and_cropped.ps])
  573. @caption[@b(a:) The raw digitized negative.  @b(b:) Cropped and rotated image]
  574. @tag(raw_pahriah)
  575. }
  576. To get the image to appear as a positive on the frame buffer, 
  577. a negative linear color map (stored as text file) is loaded, then this is
  578. composed with a gamma correction map of 2.2, and finally applied to the
  579. pixels with the command:
  580. @programExample[
  581. ldmap -f neg.cmap < neg_pahriah.rle | ldmap -a -g 2.2 \
  582.    | applymap > pahriah.rle
  583. ]
  584. The result, Figure @ref(pahriah_final) now appears correct with a linear
  585. color map loaded.
  586.  
  587. @Figure{
  588. @RLEPicture(Size=3 inch, PostScript=[pics/pahriah_final.ps])
  589. @caption[Final image of the old Pahriah ghost town]
  590. @tag(pahriah_final)
  591. }
  592.  
  593. @section(Future Work)
  594. Needless to say, a project such as the Raster Toolkit is open ended in
  595. nature, and new tools are easily added.  For example, most of the
  596. tools we have developed to date deal with image synthesis and
  597. composition, primarily because that is our research orientation.
  598. Additional tools could be added to assist work in areas such as vision
  599. research or image processing (for examples, see @cite(burt, stockham)).
  600.  
  601. Another interesting application would be a visual "shell" for invoking
  602. the tools.  Currently, arguments to programs like @F[crop] and
  603. @F[repos] are specified by tediously finding the numbers with the
  604. frame buffer cursor and then typing them into a shell.  The visual
  605. shell would allow the various toolkit operations to be interactively selected
  606. from a menu.  Such a shell could probably work directly with an
  607. existing workstation window system such as X @cite(Xwin) to provide
  608. a friendly environment for using the toolkit.
  609.  
  610. @section(Conclusions)
  611. @comment{THIS IS IRRELEVANT?
  612. The operations provided by the Raster Toolkit have been around for many
  613. years, and indeed some systems (such as the Pixar Image computer, the
  614. Quantel Paintbox, etc) implement them at full video rates using
  615. special purpose hardware.}
  616. The Raster Toolkit provides a flexible, simple and easily extended set
  617. of tools for anybody working with images in a Unix-based environment.
  618. We have ported the toolkit to a wide variety of Unix systems, including
  619. Gould UTX, HP-UX, Sun Unix, Apollo Domain/IX, 4.2 and 4.3 BSD, etc.
  620. The common interfaces of the RLE format and the subroutine library
  621. make it easy to interface the toolkit to a wide variety of image sources
  622. and displays.
  623.  
  624. @newpage
  625. @section(Acknowledgments)
  626. This work was supported in part by the National Science Foundation
  627. (DCR-8203692 and DCR-8121750), the Defense Advanced Research Projects Agency
  628. (DAAK11-84-K-0017), the Army Research Office (DAAG29-81-K-0111), and
  629. the Office of Naval Research (N00014-82-K-0351).
  630. All opinions, findings, conclusions or recommendations expressed in this
  631. document are those of the authors and do not necessarily reflect the views of
  632. the sponsoring agencies.
  633.